/*************************************************************************************
 * Nombre del archivo: CPU.java
 * Universidad del Valle de Guatemala
 * Curso: Sistemas Operativos
 * @author martin
 *          Martín Guzmán 08041
 * Fecha: Febrero de 2010
 * Descripción:
*************************************************************************************/
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;

public class CPU extends Thread{

    public volatile static Cola<Proceso> Cola_Procesos = new Cola<Proceso>();
    public volatile static Cola<Proceso> Procesos_por_matar = new Cola<Proceso>();
    public volatile static Cola<Proceso> Todos_Procesos = new Cola<Proceso>();
    public volatile static Cola<Proceso> Cola_Procesos_Terminados = new Cola<Proceso>();
    public volatile static boolean cambio_proceso = false;
    
    public volatile static Cola<Archivo> Archivos_PID = new Cola<Archivo>();//cola que contiene el archivo.

    public CPU(){

    }
    
    /***********************************************
     * Método: run
     * Uso: Método que ejecuta el CPU mientras está
     *      encendido
     *@return void
     ***********************************************/
    public void run() {

        while(true){

            if(!Cola_Procesos.isEmpty()){
                boolean temp = Exec_Proc();
                if(temp){
                    //System.out.println("terminó un proceso");
                    Cola_Procesos_Terminados.add(Cola_Procesos.poll());
                }
                if(!this.Procesos_por_matar.isEmpty()){
                    Matar_Procesos();
                }
                if(!Cola_Procesos.isEmpty()){
                    Context_Switch();
                }
            }
        }
    }

    /***********************************************
     * Método: Context_Switch
     * Uso: revisa el cambio de proceso
     *@return void
     ***********************************************/
    public boolean Exec_Proc(){
        return this.Cola_Procesos.peek().Exec();

    }

    /***********************************************
     * Método: Context_Switch
     * Uso: revisa el cambio de proceso
     *@return void
     ***********************************************/
    public void Context_Switch(){
        if(cambio_proceso){
            //System.out.println("entró a context switch");
            this.cambio_proceso=false;
            this.Cola_Procesos.add(this.Cola_Procesos.poll());
            this.Cola_Procesos.getLast().setEstado(2);//para cambiar a estado ready
        }
    }

    /***********************************************
     * Método: Matar_Procesos
     * Uso: revisa el cambio de proceso
     *@return void
     ***********************************************/
    public void Matar_Procesos(){
        CPU.Procesos_por_matar.peek().setEstado(6);
        CPU.Cola_Procesos.remove(CPU.Procesos_por_matar.poll());
    }

    /***********************************************
     * Método: Agregar_Proceso
     * Uso: Agrega un proceso a la cola
     * @param proceso contiene el proceso a agregar
     *@return void
     ***********************************************/
    public static void Agregar_Proceso(Proceso proceso){
        Todos_Procesos.add(proceso);
        Cola_Procesos.add(proceso);
        Cola_Procesos.getLast().setEstado(2);//para cambiar a estado ready
    }

    /***********************************************
     * Método: Ver_Cola_Procesos
     * Uso: ver el contenido de la cola de procesos
     *@return void
     ***********************************************/
    public static void Ver_Cola_Procesos(){

        LinkedList<Proceso> temp = Cola_Procesos.getCola();

        for(int i=0;i<temp.size();i++){
            System.out.println("Proceso: "+temp.get(i).getPID()+", estado: "+temp.get(i));
        }
    }

}
